sed는 일반적으로 gawk 보다 기능적으로 떨어질 수 있지만, 더 빠른 속도로 동작한다.
일반적으로 sed는 줄바꿈(\n)을 기준으로 스트림을 구분한다.
따라서 기본적으로 두 줄에 걸쳐 있는 패턴에 대해서 매칭할 수 없다.
N(next): 멀티라인 그룹을 만들기 위해 데이터 스트림에서 다음 줄을 추가
D(delete): 멀티라인 그룹에서 한 줄을 삭제
P(print): 멀티라인 그룹의 한 줄을 인쇄
N(next)sed 편집기에서 명령의 시작 부분으로 돌아가지 않고 데이터 스트림 텍스트의 다음 줄로 가라고 지시함
echo -e 'This is header line.\n\nThis is a data line.\n\nThis is the local line.' | sed '/^$/d'
만일 위의 예제에서 data 다음줄에 해당하는 빈줄을 제외하고 빈줄을 제외하고 싶은 경우, n 명령을 사용한다.
echo -e 'This is header line.\n\nThis is a data line.\n\nThis is the local line.' | sed '/header/{n;d}'
-> Linux에서는 문제 없이 동작하지만, MacOS에서는 "extra characters at the end of d command" Error 발생
흔히 알려진 문제인 듯 하다.
N을 이용해서 텍스트 줄을 결합하는데 사용할 수 있다.
echo 'This is the hader line.
This is the first dat line.
This is the second data line.
This is the last line.' > data.txt
sed '/first/{N; s/\n/ /}' data.txt
rm data.txt
두 줄에 걸쳐 있는 패턴에 대한 매칭
echo "On Tuesday, the Linux System
Administrator's group meeting will be held.
All System Administrators should attend.
Thank you for your attendance." > data.txt
sed 's/System Administrator/Desktop User/' data.txt
sed 'N; s/System.Administrator/Desktop User/' data.txt
sed 'N; s/System\nAdministrator/Desktop\nUser/
s/System Administrator/Desktop User/' data.txt
sed '
s/System Administrator/Desktop User/
N
s/System\nAdministrator/Desktop\nUser/' data.txt
rm data.txt
D(Delete Front Line)d: 패턴 영역의 한 줄 삭제(N을 사용한 줄이 매칭될 경우, 두 줄이 삭제됨)
D: 패턴 영역의 첫 번째 줄만을 삭제
sed 'N; /System\nAdministrator/D' data.txt
echo '
This is the header line.
This is a data line.
This is the last line.' | sed '/^$/{N; /header/D}'
P(Print Front Line)
sed -n 'N; /System\nAdministartor/P' data.txt
대기 영역패턴 영역은 sed 편집기가 검사할 텍스트를 보유하는 활성 버퍼 영역이다.
sed 편집기는 패턴 영역 외에 대기 영역이라고 불리는 다른 텍스트 줄을 임시로 보관할 수 있는 대기 영역 버퍼를 보유하고 있다.
h: 패턴 영역을 대기 영역으로 복사
H: 패턴 영역을 대기 영역으로 추가
g: 대기 영역을 패턴 영역으로 복사
G: 대기 영역을 패턴 영역에 추가
x: 패턴 영역과 대기 영역을 swap
echo -e 'This is the header line.\nThis is the first data line.\nThis is the second data line.\nThis is the last line.' > data.txt
sed -n '/first/ {h; p; n; p; g; p}' data.txt
rm data.txt
부정형 명령어패턴이 일치하지 않는 스트림에 대해서 명령어 수행
sed -n '/header/!p' data.txt
sed '$!N
s/System\nAdministrator/Desktop\nUser/
s/System Administrator/Desktop User/' data.txt
스트림의 마지막 줄을 뜻하는 $ 뒤에 !N은 마지막 줄에 이르렀을 경우, N 명령어를 수행하지 않음을 의미한다
대기 영역 명령어 + 부정형 명령어를 통한 스트림의 순서 변경각 스트림에 대한 출력을 억제하기 위해 -n 옵션 사용!
스트림 역순으로 출력하기
echo -e 'This is the header line.\nThis is the first data line.\nThis is the second data line.\nThis is the last line.' > data.txt
sed -n '{1!G; h; $p}' data.txt
rm data.txt
tac와 동일하게 출력한다.
흐름 제어일반적으로 sed 편집기 처리 명령은 스크립트의 첫 머리부터 끝 방향으로 순차적으로 진행된다.
(단, D 명령으로 sed 편집기가 새로운 텍스트가 아닌 첫 머리로 돌아가게 설정할 수 있다.)
- 분기
[address]b [label]
address: 분기 명령을 작동시킬 줄들을 지정
label: 분기할 위치를 지정(생략시, 분기 명령은 스크립트; 해당 줄 끝으로 간다. = 명령어 생략)
echo 'This is the haeder line.
This is the first data line.
This is the second data line.
This is the last line.' > data.txt
sed '{2,3b; s/This is/Is this/; s/line./test?/}' data.txt
sed '{/first/b jump1; s/This is the/No jump on/
:jump1
s/This is the/Jump here on/}' data.txt
rm data.txt
레이블을 지정하고 해당 위치로 분기하도록 할 수 있다.
:charac7 # :로 시작하고 7자까지 사용 가능
echo "This, is, a, test, to, remove, commas." | sed -n '{
:start
s/,//1p
/,/b start
}'
- 테스트주소를 기반으로 레이블로 건너뛰는 b 와 달리 테스트 t는 바꾸기 명령의 결과에 바탕을 두고 레이블로 분기한다.
[address]t [label]
label 생략 시, 명령어 생략
if-then과 유사하게 동작함
sed '{
s/first/matched
t
s/This is the/No match on/
}' data.txt
echo "This, is, a, test, to, remove, commas." | sed -n '{
:start
s/,//1p
t start
}'
test t 앞에서 s 명령이 매칭해서 바꾸는 경우, t 다음 명령은 스킵하며
첫 번째 바꾸기 명령이 패턴과 일치하지 않는 경우, 두 번째 바꾸기 명령을 수행한다.
패턴으로 바꾸기&
기존 방법으로 와일드 카드를 이용해서 패턴을 매칭할 수 있지만, 매칭했던 패턴을 다시 사용하는 것은 쉽지 않다
이 떄 &는 바꾸기 명령에서 대응되는 패턴을 표시하는데 사용된다.
echo "The cat sleeps in his hat." | sed 's/.at/"&"/g'
개별 단어 바꾸기\( \) \1 \2 ...
지정한 패턴과 일치하는 전체 문자열을 검색한 후, 문자열 가운데 일부분을 가져와야 하는 경우
sed는 패턴 안에서 부속 문자열을 정의하기 위해 괄호를 사용한다. 이 후, 특수문자를 사용하면 각각의 부속 문자열
구성요소를 참조할 수 있다.
\1 \2 ...
대체 명령에서 괄호를 사용할 때, 해당 괄호가 일반 문자가 아닌 문자를 묶기 위해서 사용한다는 뜻에서 이스케이프 문자를 사용한다.
일반적으로 사용하는 이스케이프와 반대되는 개념으로 사용하는 것임
&가 전체 패턴을 포함하는 문자열로 바꿀 때 사용한 다면, \( \)는 패턴에서 일부 단어를 포함하는 문자열로 바꿀 때 사용한다.
echo "The System Administrator manual" | sed '
s/\(System\) Administrator/\1 User/'
echo "That furry cat is pretty" | sed '
s/furry \(.at\)/\1'
숫자 1,000 단위 구분점 찍기
echo 1234567890 | sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start
}'
쉘 스크립트를 sed 래퍼로 사용함으로서 기존의 STDOUT 출력을 임의로 쉽게 리다이렉트 할 수 있다.
factorial=1
counter=1
number=$1
while [ $counter -le $number ]; do
factorial=$[ $factorial * $counter ]
counter=$[ $counter + 1 ]
done
result=$(echo $factorial | sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start
}')
echo $result
두 줄 간격으로 띄우기
sed 'G' data.txt
sed '$!G' data.txt
sed '/^$/d; $!G' data.txt
줄 번호 매기기
sed '=' data.txt
sed '=' | sed 'N; s/\n/ /'
마지막 줄에서 n번째 줄부터 출력
롤링 윈도우: N 명령을 사용하여 조합한 패턴 영역 안의 텍스트 행의 블록을 다루기 위해 사용
echo 'This is the line 1
This is the line 2
This is the line 3
This is the line 4
This is the line 5
This is the line 6
This is the line 7
This is the line 8
This is the line 9
This is the line 10
This is the line 11
This is the line 12
This is the line 13
This is the line 14
This is the line 15' | sed '{
:start
$q; N; 11,$D
b start
}'
선택적 줄 지우기
두 개이상의 연속된 빈 줄 지우기
echo -e 'This is line one.\n\n\nThis is line two.\n\n\n\nThis is line three.\n\nThis is line four' >data.txt
sed '/./,/^$/!d' data.txt
rm data.txt
시작 부분의 빈 줄 지우기
끝 부분의 빈 줄 지우기
sed '
:start
/^\n*$/{$d; N; b start}
}' data.txt
HTML 태그 제거
sed 's/<.*>///g'
.*이 < >를 포함해 버리기 대문에 <b> first </b> 와 같이 모든 본문까지 제거해 버린다.
curl www.example.com > HTMLexample.txt
sed 's/<[^>]*>//g; /^$/d' HTMLexample.txt